/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao;

import listener.IDownloadListener;
import listener.ICancelListener;
import control.MStockMidlet;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.ContentConnection;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Image;
import model.ErrorMessage;
import view.ProcessBox;

/**
 *
 * @author kien.tran
 */
public class DataLoader implements Runnable {

    public static final int CONTENT = 0;
    public static final int IMAGE = 1;
    // local
//    public static final String CONTENT_LINK = "http://172.16.0.22/XoSo/j2me/XoSo.aspx";
//    public static final String IMAGE_LINK = "http://172.16.0.22/XoSo/j2me/ImageViewer.aspx";
    //testing
//    public static final String CONTENT_LINK = "http://www.vsv.vn/xoso/j2me/xoso.aspx";
//    public static final String IMAGE_LINK = "http://www.vsv.vn/xoso/j2me/ImageViewer.aspx";
    //deploy
    public static final String CONTENT_LINK = "http://www.xoso.a4m.com.vn/j2me/xoso.aspx";
    public static final String IMAGE_LINK = "http://www.xoso.a4m.com.vn/j2me/imageviewer.aspx";
    private IDownloadListener action;
    private MStockMidlet control;
    private HttpConnection http = null;
    private ContentConnection content = null;
    private DataInputStream iStrm = null;
    private ByteArrayOutputStream bStrm = null;
    private InputStream is = null;
    private InputStreamReader isr = null;
    private OutputStream os = null;
    private String params;
    private int accent, type;
    private boolean isCancel = false;

    public DataLoader(String params, int accent, MStockMidlet control, IDownloadListener action) {
        this.params = params;
        this.action = action;
        this.control = control;
        this.accent = accent;
        this.type = CONTENT;
    }

    public DataLoader(String params, int accent, MStockMidlet control, IDownloadListener action, int type) {
        this.params = params;
        this.action = action;
        this.control = control;
        this.accent = accent;
        this.type = type;
    }

    public void run() {
        control.setCompleted(false);
        if (type == CONTENT) {
            loadDataWithThread();

        } else {
            loadDataIsImage();
        }
    }

    public void loadDataWithThread() {
        try {
            ProcessBox pb = new ProcessBox(control, this.accent);
            pb.setListener(new ICancelListener() {

                public void cancelAction() {
                    isCancel = true;
                    try {
                        if (isr != null) {
                            isr.close();
                        }

                        if (is != null) {
                            is.close();
                        }

                        if (http != null) {
                            http.close();
                        }
                        return;
                    } catch (IOException e) {
                    }
                }
            });
            pb.show();

            http = (HttpConnection) Connector.open(CONTENT_LINK);
            http.setRequestMethod(HttpConnection.POST);
            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            byte[] data = params.getBytes();
            os = http.openOutputStream();
            os.write(data);
            os.close();
            int total = (int) http.getLength();
            int count = 0;
            int percent;
            int newValue = 0;
            is = http.openInputStream();
            String re = "";
            if (http.getResponseCode() == HttpConnection.HTTP_OK) {
                isr = new InputStreamReader(is, "UTF-8");
                int ch;
                while ((ch = isr.read()) != -1) {
                    re += (char) ch;
                    count = re.length();
                    percent = (int) ((count * 1.0 / total) * 100);
                    if (newValue != percent) {
                        pb.setValue(percent);
                        newValue = percent;
                    }
//                    try {
//                        //TEST
//                        Thread.sleep(10);
//                    } catch (InterruptedException ex) {
//                        ex.printStackTrace();
//                    }
                }
                pb.setValue(99);
                http.close();
                is.close();
                isr.close();

                if (!isCancel) {
                    control.setCompleted(true);
                    action.completedAction(re.trim());
                }
            }
        } catch (IOException e) {
            try {
                if (isr != null) {
                    isr.close();
                }

                if (is != null) {
                    is.close();
                }

                if (http != null) {
                    http.close();
                }

            } catch (Exception ex) {
            }

            if (!isCancel) {
                control.setCompleted(true);
                action.completedAction(new ErrorMessage(ErrorMessage.ERROR_CONNECTION));
            }

        } finally {
            // set null
            http = null;
            is = null;
            isr = null;
        }
    }

    public void loadDataIsImage() {
        try {
            ProcessBox pb = new ProcessBox(control, this.accent);
            pb.setListener(new ICancelListener() {

                public void cancelAction() {
                    isCancel = true;
                    try {
                        if (content != null) {
                            content.close();
                        }
                        if (iStrm != null) {
                            iStrm.close();
                        }
                        if (bStrm != null) {
                            bStrm.close();
                        }
                        return;
                    } catch (IOException e) {
                    }
                }
            });
            pb.show();

            content = (ContentConnection) Connector.open(IMAGE_LINK + "?" + this.params);
            iStrm = content.openDataInputStream();
            bStrm = null;

            // ContentConnection includes a length method
            byte imageData[];
            int length = (int) content.getLength();
            if (length != -1) {
                imageData = new byte[length];
                iStrm.readFully(imageData);

            } else { // Length not available...
                bStrm = new ByteArrayOutputStream();
                int total = 0, count = 0, percent, newValue = 0;

                int ch;
                while ((ch = iStrm.read()) != -1) {
                    bStrm.write(ch);
                    count = bStrm.size();
                    if (count > total - 10) {
                        total += 100;
                    }
                    percent = (int) ((count * 1.0 / total) * 100);

                    if (newValue != percent) {
                        pb.setValue(percent);
                        newValue = percent;
                    }
                }

                imageData = bStrm.toByteArray();
            }

            pb.setValue(99);
            if (content != null) {
                content.close();
            }
            if (iStrm != null) {
                iStrm.close();
            }
            if (bStrm != null) {
                bStrm.close();
            }

            if (!isCancel) {
                control.setCompleted(true);
                if (imageData.length > 0) {
                    action.completedAction(Image.createImage(imageData, 0, imageData.length));

                } else {
                    action.completedAction(null);
                }
            }

        } catch (Exception e) {
            try {
                if (isr != null) {
                    isr.close();
                }

                if (is != null) {
                    is.close();
                }

                if (http != null) {
                    http.close();
                }

            } catch (Exception ex) {
            }

            if (!isCancel) {
                control.setCompleted(true);
                action.completedAction(new ErrorMessage(ErrorMessage.ERROR_CONNECTION));
            }
        }
    }

    public void loadDataWithoutThread() {
        try {
            http = (HttpConnection) Connector.open(CONTENT_LINK);
            if (http != null) {
                http.setRequestMethod(HttpConnection.POST);
                http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

                byte[] data = params.getBytes();

                os = http.openOutputStream();
                if (os != null) {
                    os.write(data);
                    os.close();

                    is = http.openInputStream();
                    if (is != null) {
                        String result = "";
                        if (http.getResponseCode() == HttpConnection.HTTP_OK) {
                            isr = new InputStreamReader(is, "UTF-8");
                            if (isr != null) {
                                int ch;
                                while ((ch = isr.read()) != -1) {
                                    result += (char) ch;
                                }
                                http.close();
                                is.close();
                                isr.close();

                                action.completedAction(result.trim());
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            try {
                if (isr != null) {
                    isr.close();
                }

                if (is != null) {
                    is.close();
                }

                if (http != null) {
                    http.close();
                }

            } catch (Exception ex) {
            }

            action.completedAction(new ErrorMessage(ErrorMessage.ERROR_GPRS));
            
        } catch (SecurityException se) {
            action.completedAction(new ErrorMessage(ErrorMessage.ERROR_DENIED));
            
        } finally {
            // set null
            http = null;
            is = null;
            isr = null;
        }
    }
}
